const { rootCertificates } = require('tls');

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var port = process.env.PORT || 5050;

app.get('/', function (req, res) {
	res.sendFile(__dirname + '/index.html');
});

var matchlist = {};
var usersOnline = {};
var rooms = {};
var sockets = {};
var maxuser = 2;


io.of(/^\/.+$/).on('connect', function (socket) {
	var nsp = socket.nsp;
	nsp.maxuser = maxuser;


	var cancelMatch = function () {
		if (matchlist[nsp.name]) {
			var index = matchlist[nsp.name].indexOf(socket);
			if (index !== -1) {
				matchlist[nsp.name].splice(index, 1);
				//console.log(socket.username + "退出排队",);
			}
		}

	};

	var leaveRoom = function (roomname) {
		roomname = nsp.name + "_" + roomname;
		if (socket.rooms[roomname]) {
			var index = rooms[roomname].userlist.indexOf(socket.username);
			rooms[roomname].userlist.splice(index, 1);
			socket.leave(roomname);
			delete socket.rooms[roomname];

			var data = {};
			data.eventname = "otherLeftRoom";
			data.username = socket.username;
			data.roomname = roomname.replace(nsp.name + "_", "");
			data.userlist = rooms[roomname].userlist;
			nsp.in(roomname).emit('otherLeftRoom', data);
			//console.log(data);
			if (data.userlist.length <= 0) {
				delete rooms[roomname];
				//console.log(roomname +"已销毁");
			}

			data = {};
			data.eventname = "leftRoom";
			data.roomname = roomname.replace(nsp.name + "_", "");
			socket.emit("leftRoom", data);




		}
	};


	socket.on("login", function (username) {
		if (!socket.username) {
			if (!usersOnline[socket.nsp.name]) { usersOnline[socket.nsp.name] = [] }
			var index = usersOnline[socket.nsp.name].indexOf(username);
			if (index == -1) {
				socket.username = username;
				usersOnline[socket.nsp.name].push(username);
				sockets[username] = socket;
				var data = {};
				data.eventname = "connected";
				data.username = username;
				//data.useronline = usersOnline[socket.nsp.name];
				data.usernum = usersOnline[socket.nsp.name].length;
				socket.emit("connected", data);
				//console.log(data);
			} else {
				var data = {};
				data.eventname = "gotError";
				data.code = 1;
				data.desc = "duplicate username";
				socket.emit("gotError", data);
			}
		}
	});

	socket.on("joinRoom", function (roomname) {
		roomname = nsp.name + "_" + roomname;
		if (socket.username) {
			if (!socket.rooms[roomname]) {

				if (!rooms[roomname]) {
					rooms[roomname] = {};
					rooms[roomname].userlist = [];
				}
				if (rooms[roomname].userlist.length >= nsp.maxuser) {
					var data = {};
					data.eventname = "gotError";
					data.code = 4;
					data.desc = "room full";
					socket.emit("gotError", data);
				} else {
					rooms[roomname].userlist.push(socket.username);

					socket.join(roomname);
					socket.rooms[roomname] = roomname;
					var data = {};
					
					data.eventname = "joinedRoom";
					data.roomname = roomname.replace(nsp.name + "_", "");
					data.username = socket.username;
					data.usernum = rooms[roomname].userlist.length;
					data.userlist = rooms[roomname].userlist;
                    socket.emit("joinedRoom", data);
                    //console.log(data);
                    
                    data.eventname = "otherJoinedRoom";
					socket.to(roomname).emit('otherJoinedRoom', data);
					//console.log(data);

				}

			}

		}
	});


	socket.on("startMatch", function () {
		if (socket.username) {
			if (!matchlist[nsp.name]) {
				matchlist[nsp.name] = [];
			}
			var index = matchlist[nsp.name].indexOf(socket);
			if (index == -1) {
				matchlist[nsp.name].push(socket);
				if (matchlist[nsp.name].length >= nsp.maxuser) {

					var roomname = nsp.name + "_" + Date.now();
					var userlist = [];
					if (!rooms[roomname]) {
						rooms[roomname] = {};
						rooms[roomname].userlist = [];
					}
					for (var i = 0; i < nsp.maxuser; i++) {
						matchlist[nsp.name][i].join(roomname);
						matchlist[nsp.name][i].rooms[roomname] = roomname;
						userlist.push(matchlist[nsp.name][i].username);
					}
					matchlist[nsp.name].splice(0, nsp.maxuser);
					rooms[roomname].userlist = userlist;
					var data = {};
					data.eventname = "matched";
					data.roomname = roomname.replace(nsp.name + "_", "");
					data.userlist = userlist
					nsp.in(roomname).emit('matched', data);
					//console.log(data);
				}
				//console.log("当前排队人数"+matchlist[nsp.name].length);
			}
		} else {
			var data = {};
			data.eventname = "gotError";
			data.code = 2;
			data.desc = "not logedin";
			socket.emit("gotError", data);
		}

	});

	socket.on('sendRoomMessage', function (roomname, message) {
		roomname = nsp.name + "_" + roomname;
		if (socket.rooms[roomname]) {
			var data = {};
			data.eventname = "gotRoomMessage";
			data.from = socket.username;
			data.roomname = roomname.replace(nsp.name + "_", "");
			data.message = message;
			nsp.in(roomname).emit('gotRoomMessage', data);
			//console.log(data);
		} else {
			var data = {};
			data.eventname = "gotError";
			data.code = 3;
			data.desc = "not in room: " + roomname.replace(nsp.name + "_", "");
			socket.emit("gotError", data);
		}
	});

	socket.on('sendPrivateMessage', (receiver, message) => {
		if (sockets[receiver] && sockets[receiver].nsp.name == socket.nsp.name) {
			var data = {};
			data.eventname = "gotPrivateMessage";
			data.from = socket.username;
			data.message = message;
			sockets[receiver].emit('gotPrivateMessage', data);
			//console.log(data);
		} else {
			var data = {};
			data.eventname = "gotError";
			data.code = 6;
			data.desc = "no such user";
			socket.emit("gotError", data);
		}
	});

	socket.on('sendPublicMessage', (message) => {
		var data = {};
		data.eventname = "gotPublicMessage";
		data.from = socket.username;
		data.message = message;
		nsp.emit('gotPublicMessage', data);
		//console.log(data);
	});

	socket.on("cancelMatch", cancelMatch);
	socket.on('leaveRoom', leaveRoom);

	socket.on('disconnect', function () {
		cancelMatch();
		leaveRoom();
		if (socket.username) {
			var index = usersOnline[socket.nsp.name].indexOf(socket.username);
			usersOnline[socket.nsp.name].splice(index, 1);
			delete sockets[socket.username];
			socket.username = null;
		}
	});

	socket.on('setMaxUser', function (max) {
		nsp.maxuser = max;
	});
});

http.listen(port, function () {
	console.log('socketio chat server listening on *:' + port);
});